package com.haocjia.esdemo.elastic.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haocjia.esdemo.elastic.annotation.EsFields;
import com.haocjia.esdemo.elastic.enums.FieldType;

import java.lang.reflect.Field;
import java.util.*;

public class MappingUtils {

    public static Map<String, Object> objToMap(Object obj) throws IllegalAccessException, JsonProcessingException {
        Map<String, Object> map = new HashMap<>();

        List<Field> fieldList = new ArrayList<>();
        Class<?> tempClass = obj.getClass();

        while (tempClass != null) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass();
        }

        for (Field field : fieldList) {
            field.setAccessible(true);
            if (field.getAnnotation(EsFields.class) == null) {
                continue;
            }
            System.out.println(field.getName() + "的类型：" + field.getType() + ", obj: " + field.get(obj));
            System.out.println(field.getType().getTypeName() + " 类型: " + field.getType().isAssignableFrom(FieldType.OBJECT.getType()));
            if (field.getType() == FieldType.LONG.getType()) {
                map.put(field.getName(), field.get(obj) != null ? field.get(obj).toString() : "");
            } else if (field.getType().isAssignableFrom(FieldType.OBJECT.getType())) {
                map.put(field.getName(), new ObjectMapper().writeValueAsString(field.get(obj)));
            } else {
                map.put(field.getName(), field.get(obj));
            }

        }
        return map;
    }

    public static Map<String, Object> getMapping(Object obj) {
        Map<String, Object> properties = new HashMap<>();
        Map<String, Object> fieldMap = new HashMap<>();

        List<Field> fieldList = new ArrayList<>();
        Class<?> tempClass = obj.getClass();

        while (tempClass != null) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass();
        }

        for (Field field : fieldList) {
            field.setAccessible(true);
            if (field.getAnnotation(EsFields.class) == null) {
                continue;
            }
            fieldMap.put(field.getName(), fieldToJson(field.getType()));
        }
        properties.put("properties", fieldMap);
        return properties;
    }

    public static Map<String, Object> fieldToJson(Class<?> type) {
        String val = null;
        if (FieldType.STRING.getType().equals(type)) {
            val = FieldType.STRING.getVal();
        }
        if (FieldType.DOUBLE.getType().equals(type)
                || FieldType.FLOAT.getType().equals(type)
                || FieldType.LONG.getType().equals(type)
                || FieldType.BIGDECIMAL.getType().equals(type)
                || FieldType.INT.getType().equals(type)
        ) {
            val = FieldType.LONG.getVal();
        }

        if (FieldType.BOOLEAN.getType().equals(type)) {
            val = FieldType.BOOLEAN.getVal();
        }

        if (val == null) {
            val = "text";
        }

        Map<String, Object> map = new HashMap<>();
        map.put("type", val);
        if (val.equals("text")) {
            map.put("analyzer", "ik_max_word");
            map.put("search_analyzer", "ik_smart");
        }
        Map<String, Object> fields = new HashMap<>();
        Map<String, Object> keys = new HashMap<>();
        keys.put("type", "keyword");
        keys.put("ignore_above", "256");
        fields.put("keyword", keys);
        map.put("fields", fields);
        return map;
    }

}
